﻿using Aspose.Words.Saving;
using Aspose.Words;
using Aspose.Words.Tables;
using Dm.util;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Document = Aspose.Words.Document;
using ConvertUtil = Aspose.Words.ConvertUtil;
using ParagraphAlignment = Aspose.Words.ParagraphAlignment;
using LineStyle = Aspose.Words.LineStyle;
using MediatR;
using T.Common.Domain.Common;
using RedDragon.Common.Domain.Purchase;
using RedDragon.ERP.API.Application.Commands.Purchases;
using RedDragon.Common.Dtos;

namespace RedDragon.ERP.API.Controllers
{
    /// <summary>
    /// 打印采购/委外订单
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class StampController : ControllerBase
    {
        private readonly IMediator _mediator;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mediator"></param>
        public StampController(IMediator mediator)
        {
            _mediator = mediator;
        }

        /// <summary>
        /// 定义一个HTTP GET方法，用于生成并返回PDF文件
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetPDF")]
        public async Task<IActionResult> GetPDF(int Id)
        {
            //获取订单
            var data = await PurchaseOutsourcesFind(new StampPurchaseCommand() { PurchaseId = Id });
            var purchaseOutsources = data.Data;
            //根据订单编码获取订单行
            var order = await OrderBankList(new StampOrderBankCommand() { PurchaseNumber = purchaseOutsources.PurchaseNumber });
            var orderbank = order.Data;
            // 异步调用CreatePDF方法生成PDF文档
            var document = await CreatePDF(purchaseOutsources, orderbank);

            // 设置PDF保存选项，包括保存格式为PDF和在新窗口中打开超链接
            var saveOptions = new PdfSaveOptions
            {
                SaveFormat = SaveFormat.Pdf,
                OpenHyperlinksInNewWindow = true
            };

            // 创建一个MemoryStream用于保存PDF文档
            var docStream = new MemoryStream();

            // 将文档保存到MemoryStream中，使用之前设置的保存选项
            document.Save(docStream, saveOptions);

            // 将MemoryStream转换为字节数组，以便作为HTTP响应返回
            byte[] pdfBytes = docStream.ToArray();

            // 以PDF文件的格式返回字节数组，并设置文件名为"generated_document.pdf"
            // "application/pdf"是MIME类型，告诉客户端这是一个PDF文件
            return File(pdfBytes, "application/pdf", "generated_document.pdf");
        }

        /// <summary>
        /// 采购订单
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private async Task<Result<PurchaseOutsourcesDto>> PurchaseOutsourcesFind([FromQuery] StampPurchaseCommand cmd)
        {
            return await _mediator.Send(cmd);
        }

        /// <summary>
        /// 获取订单行信息
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private async Task<Result<List<OrderBankDto>>> OrderBankList([FromQuery] StampOrderBankCommand cmd)
        {
            return await _mediator.Send(cmd);
        }

        /// <summary>
        /// 打印样式大小
        /// </summary>
        /// <returns></returns>
        private async Task<Document> CreatePDF(PurchaseOutsourcesDto purchaseOutsource, List<OrderBankDto> orderbank)
        {
            // 创建一个新的PDF文档对象
            var document = new Document();

            // 创建一个DocumentBuilder对象，用于构建PDF文档内容
            var builder = new DocumentBuilder(document)
            {
                // 设置页面布局选项
                PageSetup =
                {
                    // 页面宽度和高度设置为A4纸的纵向尺寸（毫米转换为点）
                    // A4纸标准尺寸：宽210毫米，高297毫米
                    // 1英寸 = 72点，1毫米 ≈ 0.264583点（或 1点 ≈ 3.779528毫米）
                    PageWidth = ConvertUtil.MillimeterToPoint(450),
                    PageHeight = ConvertUtil.MillimeterToPoint(297),
                    Orientation = Orientation.Portrait, // 纵向布局
                    // 设置页边距（毫米转换为点）
                    TopMargin = ConvertUtil.MillimeterToPoint(25.4), // 例如，1英寸边距
                    BottomMargin = ConvertUtil.MillimeterToPoint(25.4), // 例如，1英寸边距
                    LeftMargin = ConvertUtil.MillimeterToPoint(25.4), // 例如，1英寸边距
                    RightMargin = ConvertUtil.MillimeterToPoint(25.4)  // 例如，1英寸边距
                    // 注意：这里的边距值可以根据需要调整，上面示例中使用了1英寸的边距
                }
            };

            // 调用方法设置文档的标题
            DocumentTitle(builder, "赤龙ERP公司");

            // 调用方法设置文档的头部
            DocumentHead(builder, purchaseOutsource);

            // 调用方法设置产品流程表的头部
            ProductProcessHead(builder);

            // 调用方法填充产品流程表的内容
            ProductProcess(builder, orderbank);

            // 调用方法设置签名流程
            SignProcess(builder, purchaseOutsource);

            // 由于CreatePDF方法被定义为异步，但在此示例中并没有实际的异步操作，
            // 因此使用Task.FromResult来同步返回document对象。
            // 在实际应用中，如果创建文档涉及I/O操作或其他耗时任务，则应使用真正的异步方法。
            return await Task.FromResult(document);
        }

        /// <summary>
        /// 设置文档的标题
        /// </summary>
        /// <param name="builder">文档构建器，用于操作文档内容</param>
        /// <param name="title">标题文本，将显示在销售单标题中</param>
        private void DocumentTitle(DocumentBuilder builder, string title)
        {
            // 清除当前单元格格式，以确保设置的新格式生效
            builder.CellFormat.ClearFormatting();

            // 设置标题字体大小为16，字体为黑体，居中对齐
            builder.Font.Size = 16;
            builder.Font.NameFarEast = "黑体";
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;

            // 写入标题文本，后接" 销售单"字样
            builder.Writeln(title + " 采购/销售订单");
        }

        /// <summary>
        /// 创建并设置文档的表头
        /// </summary>
        /// <param name="builder">文档构建器，用于操作文档内容</param>
        /// <param name="purchaseOutsource"></param>
        private void DocumentHead(DocumentBuilder builder, PurchaseOutsourcesDto purchaseOutsource)
        {
            // 设置字体大小为12
            builder.Font.Size = 12;

            // 开始创建表格
            builder.StartTable();

            // 清除当前单元格格式，设置无边框，左对齐文本
            builder.CellFormat.ClearFormatting();
            builder.CellFormat.Borders.LineStyle = LineStyle.None;
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
            // 设置当前单元格顶部的内边距为1毫米，转换为点单位
            // 内边距是指单元格内容与单元格边框之间的空间
            builder.CellFormat.TopPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(1);
            // 设置当前单元格的文本适应功能为启用
            builder.CellFormat.FitText = true;

            // 插入第一个单元格，写入"订单编号:"，并设置单元格宽度和左填充
            builder.InsertCell();
            builder.Write("订单编号:");
            // 调整宽度以适应内容，这里假设内容不会太长
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 调整填充

            // 插入第二个单元格，写入编号，并设置单元格宽度和左填充
            builder.InsertCell();
            builder.Write(purchaseOutsource.PurchaseNumber);
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 保持填充一致

            builder.InsertCell();
            builder.Write("订单名称:");
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 调整填充

            builder.InsertCell();
            builder.Write(purchaseOutsource.PurchaseName);
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(40); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 保持填充一致

            builder.InsertCell();
            builder.Write("供应商:");
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 调整填充

            builder.InsertCell();
            builder.Write(purchaseOutsource.SupplierName);
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50); // 调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 保持填充一致

            builder.InsertCell();
            builder.Write("打印时间:");
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度                    
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0);// 由于无边框且内容较短，可以减少或移除左填充

            builder.InsertCell();
            builder.Write(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(40); // 根据内容调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 移除左填充以保持布局整洁

            // 结束当前行
            builder.EndRow();

            // 结束表格创建
            builder.EndTable();
        }

        /// <summary>
        /// 表体表格的 表头
        /// </summary>
        /// <param name="builder">用于构建文档的DocumentBuilder对象。</param>
        private void ProductProcessHead(DocumentBuilder builder)
        {
            // 开始创建表格
            var productTable = builder.StartTable();

            // 设置表格边框为无（实际可能用于后续覆盖单元格边框）
            productTable.SetBorders(LineStyle.None, 0d, System.Drawing.Color.White);

            // 为后续添加的单元格设置边框、字体、对齐方式等
            builder.CellFormat.Borders.LineStyle = LineStyle.Single;
            builder.Font.NameFarEast = "黑体"; // 设置字体为黑体
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; // 段落水平居中对齐
            builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; // 单元格内容垂直居中对齐
            builder.Font.Size = 12; // 设置字体大小为12

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("行号");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("物料编码");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("物料名称");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("单价(不含税)");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("数量");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("单位");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("金额(不含税)");

            builder.InsertCell();
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
            builder.Write("摘要");

            // 注意：此处未添加任何单元格或行，表头内容需要在后续步骤中添加
            builder.EndTable(); // 结束表格创建
        }
        /// <summary>
        /// 表格内容
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="orderbank"></param>
        private void ProductProcess(DocumentBuilder builder, List<OrderBankDto> orderbank)
        {
            // 开始创建表格
            builder.StartTable();
            // 设置段落和单元格的对齐方式
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
            builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;

            foreach (var item in orderbank)
            {
                // 行号
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.OrderBankId.ToString());
                // 物料编码
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.MaterialCode);
                // 物料名称
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.MaterialName);
                // 单价(不含税)
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.Unitprice.ToString("0.00"));
                // 数量
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.Quantity.ToString());
                // 单位
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.UnitName.ToString());
                // 金额(不含税)
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.BankAmount.ToString("0.00"));
                // 摘要
                builder.InsertCell();
                builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(50);
                builder.Write(item.Abstract);

                builder.EndRow();
            }

            // 结束表格创建
            builder.EndTable();
        }
        /// <summary>
        /// 页脚
        /// </summary>
        /// <param name="builder">用于构建文档的DocumentBuilder对象。</param>
        private void SignProcess(DocumentBuilder builder, PurchaseOutsourcesDto purchaseOutsource)
        {
            // 开始创建页脚表格
            var signTable = builder.StartTable();

            // 设置字体大小和边框（无边框，因为可能使用单元格内部的边框样式）
            builder.Font.Size = 12;
            builder.CellFormat.Borders.LineStyle = LineStyle.None;
            builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
            // 设置当前单元格顶部的内边距为1毫米，转换为点单位
            // 内边距是指单元格内容与单元格边框之间的空间
            builder.CellFormat.TopPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(1);
            // 设置当前单元格的文本适应功能为启用
            builder.CellFormat.FitText = true;

            // 设置行高
            builder.RowFormat.Height = Aspose.Words.ConvertUtil.MillimeterToPoint(4);

            builder.InsertCell();
            builder.Write("创建人:");
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度                    
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0);// 由于无边框且内容较短，可以减少或移除左填充

            builder.InsertCell();
            builder.Write(purchaseOutsource.CreatedOwner);
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(40); // 根据内容调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 移除左填充以保持布局整洁

            builder.InsertCell();
            builder.Write("创建时间:");
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(26); // 调整宽度                    
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0);// 由于无边框且内容较短，可以减少或移除左填充

            builder.InsertCell();
            builder.Write(purchaseOutsource.CreatedTime.ToString());
            builder.CellFormat.Width = Aspose.Words.ConvertUtil.MillimeterToPoint(40); // 根据内容调整宽度
            builder.CellFormat.LeftPadding = Aspose.Words.ConvertUtil.MillimeterToPoint(0); // 移除左填充以保持布局整洁

            // 结束当前行
            builder.EndRow();

            // 结束表格创建
            builder.EndTable();
        }
    }
}
